package com.auto.autoapp.widgets

import android.content.Context
import android.graphics.Color
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.EditText
import android.widget.TextView
import com.auto.autoapp.R
import com.auto.autoapp.databinding.ViewSettingItemBinding
import com.auto.autoapp.databinding.ViewSettingItemRowBinding

class SettingItemView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private val binding: ViewSettingItemBinding =
        ViewSettingItemBinding.inflate(LayoutInflater.from(context), this, true)

    private var allowMultiple: Boolean = true
    private var hintText: String? = null
    private var inputTypeInternal: Int = InputType.TYPE_CLASS_TEXT
    private var unitText: String? = null
    private var inlineTitle: Boolean = false
    private var titleTextInternal: String = ""
    private var onChildFocusListener: ((View) -> Unit)? = null
    private var requiredInternal: Boolean = false
    private var titleMinWidthPx: Int = 0
    private var showBottomDividerInternal: Boolean = false

    init {
        val a = context.obtainStyledAttributes(attrs, R.styleable.SettingItemView)
        val title = a.getString(R.styleable.SettingItemView_titleText)
        val actionText = a.getString(R.styleable.SettingItemView_actionText)
        val showAction = a.getBoolean(R.styleable.SettingItemView_showAction, true)
        allowMultiple = a.getBoolean(R.styleable.SettingItemView_allowMultiple, true)
        inlineTitle = a.getBoolean(R.styleable.SettingItemView_inlineTitle, false)
        hintText = a.getString(R.styleable.SettingItemView_hintText)
        val inputTypeAttr = a.getInt(R.styleable.SettingItemView_inputType, 1) // default text
        unitText = a.getString(R.styleable.SettingItemView_unitText)
        requiredInternal = a.getBoolean(R.styleable.SettingItemView_required, false)
        titleMinWidthPx = a.getDimensionPixelSize(R.styleable.SettingItemView_titleMinWidth, 0)
        showBottomDividerInternal = a.getBoolean(R.styleable.SettingItemView_showBottomDivider, false)
        a.recycle()

        titleTextInternal = title ?: ""
        binding.tvTitle.text = displayTitleStyled()
        binding.btnAction.text = actionText ?: "添加"
        binding.btnAction.visibility = if (showAction && allowMultiple) View.VISIBLE else View.GONE

        setInputType(mapInputType(inputTypeAttr))

        binding.btnAction.setOnClickListener {
            addRow(removable = true)
            updateDeleteButtons()
        }

        // 默认添加一个输入框
        addRow(removable = false)
        updateDeleteButtons()

        // 分割线显示控制
        binding.bottomDivider.visibility = if (showBottomDividerInternal) View.VISIBLE else View.GONE

        // inlineTitle 仅在非多项时生效：隐藏头部，标题在行内显示
        if (inlineTitle && !allowMultiple) {
            binding.header.visibility = View.GONE
        } else {
            binding.header.visibility = View.VISIBLE
        }
    }

    private fun mapInputType(attrValue: Int): Int = when (attrValue) {
        2 -> InputType.TYPE_CLASS_NUMBER
        else -> InputType.TYPE_CLASS_TEXT
    }

    private fun addRow(removable: Boolean) {
        val rowBinding = ViewSettingItemRowBinding.inflate(LayoutInflater.from(context), binding.container, false)
        rowBinding.etValue.inputType = inputTypeInternal
        hintText?.let { rowBinding.etValue.hint = it }
        // 单位设置
        if (!unitText.isNullOrEmpty()) {
            rowBinding.tvUnit.text = unitText
            rowBinding.tvUnit.visibility = View.VISIBLE
        } else {
            rowBinding.tvUnit.visibility = View.GONE
        }
        // 左右结构：在行内显示标题
        if (inlineTitle && !allowMultiple) {
            rowBinding.tvInlineTitle.text = displayTitleStyled()
            if (titleMinWidthPx > 0) {
                rowBinding.tvInlineTitle.minWidth = titleMinWidthPx
            }
            rowBinding.tvInlineTitle.visibility = View.VISIBLE
        } else {
            rowBinding.tvInlineTitle.visibility = View.GONE
        }
        // 焦点回调，便于外部滚动到此输入框
        rowBinding.etValue.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) onChildFocusListener?.invoke(v)
        }
        rowBinding.btnDelete.visibility = if (allowMultiple && removable) View.VISIBLE else View.GONE
        rowBinding.btnDelete.setOnClickListener {
            binding.container.removeView(rowBinding.root)
            if (binding.container.childCount == 0) {
                addRow(removable = false)
            }
            updateDeleteButtons()
        }
        binding.container.addView(rowBinding.root)
    }

    private fun updateDeleteButtons() {
        val count = binding.container.childCount
        for (i in 0 until count) {
            val child = binding.container.getChildAt(i)
            val delete: ImageButton? = child.findViewById(R.id.btn_delete)
            delete?.visibility = if (allowMultiple && count > 1) View.VISIBLE else View.GONE
        }
    }

    fun setTitle(text: String) {
        binding.tvTitle.text = text
    }

    fun setActionText(text: String) {
        binding.btnAction.text = text
    }

    fun setActionVisible(visible: Boolean) {
        binding.btnAction.visibility = if (visible && allowMultiple) View.VISIBLE else View.GONE
    }

    fun setAllowMultiple(allow: Boolean) {
        allowMultiple = allow
        setActionVisible(binding.btnAction.visibility == View.VISIBLE)
        updateDeleteButtons()
    }

    fun setHint(text: String?) {
        hintText = text
        val count = binding.container.childCount
        for (i in 0 until count) {
            val et: EditText? = binding.container.getChildAt(i).findViewById(R.id.et_value)
            et?.hint = text
        }
    }

    fun setUnitText(text: String?) {
        unitText = text
        val count = binding.container.childCount
        for (i in 0 until count) {
            val unitView: android.widget.TextView? = binding.container.getChildAt(i).findViewById(R.id.tv_unit)
            if (!unitText.isNullOrEmpty()) {
                unitView?.text = unitText
                unitView?.visibility = View.VISIBLE
            } else {
                unitView?.visibility = View.GONE
            }
        }
    }

    fun setInputType(type: Int) {
        inputTypeInternal = type
        val count = binding.container.childCount
        for (i in 0 until count) {
            val et: EditText? = binding.container.getChildAt(i).findViewById(R.id.et_value)
            et?.inputType = inputTypeInternal
        }
    }

    fun getValues(): List<String> {
        val values = mutableListOf<String>()
        val count = binding.container.childCount
        for (i in 0 until count) {
            val et: EditText? = binding.container.getChildAt(i).findViewById(R.id.et_value)
            values.add(et?.text?.toString() ?: "")
        }
        return values
    }

    fun setValues(values: List<String>) {
        binding.container.removeAllViews()
        if (values.isEmpty()) {
            addRow(removable = false)
        } else {
            values.forEachIndexed { index, v ->
                val rowBinding = ViewSettingItemRowBinding.inflate(LayoutInflater.from(context), binding.container, false)
                rowBinding.etValue.inputType = inputTypeInternal
                hintText?.let { rowBinding.etValue.hint = it }
                if (!unitText.isNullOrEmpty()) {
                    rowBinding.tvUnit.text = unitText
                    rowBinding.tvUnit.visibility = View.VISIBLE
                } else {
                    rowBinding.tvUnit.visibility = View.GONE
                }
                if (inlineTitle && !allowMultiple) {
                    rowBinding.tvInlineTitle.text = displayTitleStyled()
                    if (titleMinWidthPx > 0) {
                        rowBinding.tvInlineTitle.minWidth = titleMinWidthPx
                    }
                    rowBinding.tvInlineTitle.visibility = View.VISIBLE
                } else {
                    rowBinding.tvInlineTitle.visibility = View.GONE
                }
                rowBinding.etValue.setText(v)
                rowBinding.etValue.setOnFocusChangeListener { view, hasFocus ->
                    if (hasFocus) onChildFocusListener?.invoke(view)
                }
                rowBinding.btnDelete.visibility = if (allowMultiple && values.size > 1) View.VISIBLE else View.GONE
                rowBinding.btnDelete.setOnClickListener {
                    binding.container.removeView(rowBinding.root)
                    if (binding.container.childCount == 0) {
                        addRow(removable = false)
                    }
                    updateDeleteButtons()
                }
                binding.container.addView(rowBinding.root)
            }
        }
        updateDeleteButtons()
    }

    fun setOnActionClickListener(listener: (SettingItemView) -> Unit) {
        binding.btnAction.setOnClickListener {
            listener(this)
            // 默认行为：添加一行
            if (allowMultiple) {
                addRow(removable = true)
                updateDeleteButtons()
            }
        }
    }

    fun setOnChildFocusListener(listener: (View) -> Unit) {
        onChildFocusListener = listener
        // 立即对已存在的输入框设置监听
        val count = binding.container.childCount
        for (i in 0 until count) {
            val et: EditText? = binding.container.getChildAt(i).findViewById(R.id.et_value)
            et?.onFocusChangeListener = View.OnFocusChangeListener { v, hasFocus ->
                if (hasFocus) onChildFocusListener?.invoke(v)
            }
        }
    }

    /** 设置底部分割线显示/隐藏 */
    fun setShowBottomDivider(show: Boolean) {
        showBottomDividerInternal = show
        binding.bottomDivider.visibility = if (showBottomDividerInternal) View.VISIBLE else View.GONE
    }

    /** 是否显示底部分割线 */
    fun isBottomDividerShown(): Boolean = showBottomDividerInternal

    /** 是否为必填项 */
    fun isRequired(): Boolean = requiredInternal

    /** 设置必填并刷新标题标识 */
    fun setRequired(required: Boolean) {
        requiredInternal = required
        binding.tvTitle.text = displayTitleStyled()
        // 更新每一行 inline 标题
        val count = binding.container.childCount
        for (i in 0 until count) {
            val tv: TextView? = binding.container.getChildAt(i).findViewById(R.id.tv_inline_title)
            tv?.text = displayTitleStyled()
            if (titleMinWidthPx > 0) {
                tv?.minWidth = titleMinWidthPx
            }
        }
    }

    /** 动态设置行内标题的最小宽度（像素） */
    fun setTitleMinWidthPx(px: Int) {
        titleMinWidthPx = px
        val count = binding.container.childCount
        for (i in 0 until count) {
            val tv: TextView? = binding.container.getChildAt(i).findViewById(R.id.tv_inline_title)
            if (titleMinWidthPx > 0) tv?.minWidth = titleMinWidthPx
        }
    }

    /**
     * 当为必填时校验至少一个非空值；失败时在第一个输入框标注错误并聚焦。
     */
    fun validateRequired(errorText: String = "此项为必填"): Boolean {
        if (!requiredInternal) return true
        val values = getValues().map { it.trim() }
        val ok = values.any { it.isNotEmpty() }
        if (!ok && binding.container.childCount > 0) {
            val firstEt: EditText? = binding.container.getChildAt(0).findViewById(R.id.et_value)
            firstEt?.error = errorText
            firstEt?.requestFocus()
        }
        return ok
    }

    /** 清除所有行的错误提示 */
    fun clearErrors() {
        val count = binding.container.childCount
        for (i in 0 until count) {
            val et: EditText? = binding.container.getChildAt(i).findViewById(R.id.et_value)
            et?.error = null
        }
    }

    private fun displayTitleStyled(): CharSequence {
        return if (requiredInternal) {
            val builder = SpannableStringBuilder()
            val star = "*"
            builder.append(star)
            builder.setSpan(
                ForegroundColorSpan(Color.RED),
                0,
                star.length,
                android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            builder.append(" ")
            builder.append(titleTextInternal)
            builder
        } else {
            titleTextInternal
        }
    }
}